// LinkQueue.cpp
// 队列的链式存储结构

enum Status
{
    OK = 0,
    ERROR = 1,
};

typedef struct QNode
{
    int data;
    struct QNode *next;
}QNode, *QueuePtr;

typedef struct
{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;

Status InitQueue(LinkQueue &Q)
{
    QNode *head = new QNode;

    if(!head)
    {
        return ERROR;
    }

    head->data = 0;
    head->next = NULL;

    Q.front = head;
    Q.rear = head;

    return OK;
}

Status DestroyQueue(LinkQueue &Q)
{
    while(Q.front)
    {
        Q.rear = Q.front->next;
        delete(Q.front);
        Q.front = Q.rear;
    }

    return OK;
}

Status ClearQueue(LinkQueue& Q)
{
    QNode *head = Q.fornt;
    QNode *temp = head->next;

    while(temp)
    {
        QNode *temp2 = temp->next;

        temp->data = 0;
        temp->next = NULL;
        delete(temp);

        temp = temp2;
    }
    
    Q.rear = Q.front;

    return OK;
}

bool QueueEmpty(LinkQueue Q)
{
    if(Q.front && Q.rear)
    {
        if(Q.front == Q.rear)
        {
            return true;
        }
    }

    return false;
}

int QueueLength(LinkQueue Q)
{
    int length = 0;

    QNode *temp = Q.front->next;

    while(temp)
    {
        length++;
        temp = temp->next;
    }

    return length;
}

Status GetHead(LinkQueue Q, int &e)
{
    if(QueueEmpty(Q))
    {
        return ERROR;
    }

    if(Q.front && Q.front->next)
    {
        e = Q.front->next->data;

        return OK;
    }

    return ERROR;
}

Status EnQueue(LinkQueue &Q, int e)
{
    QNode *tail = Q.rear;

    QNode *temp = new QNode;

    if(!temp)
    {
        return ERROR;
    }

    temp->data = e;
    temp->next = NULL;

    tail->next = temp;

    Q.rear = temp;

    return OK;
}

Status DeQueue(LinkQueue &Q, int &e)
{
    if(QueueEmpty(Q))
    {
        return ERROR;
    }

    QNode *head = Q.front->next;

    QNode *headNext = head->next;

    e = head->data;
    head->data = 0;
    head->next = NULL;

    Q.front->next = headNext;

    if(Q.rear == head)
    {
        Q.rear = Q.front;
    }
    
    delete(head);

    return OK;
}

Status QueueTraverse(LinkQueue &Q, visit())
{
    if(!Q || !Q.front || !Q.rear)
    {
        return ERROR;
    }

    if(QueueEmpty(Q))
    {
        return ERROR;
    }

    QNode *temp = Q.front->next;

    while(temp)
    {
        int data = temp->data;
        if(!data->visit())
        {
            return ERROR;
        }
        temp = temp->next;
    }

    return OK;
}
